﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Guoling.ProjectName.Data;
using Microsoft.EntityFrameworkCore;

namespace Guolian.ProjectName.Infrastruct
{
    public class BaseRepository<T> : IBaseRepository<T> where T : class
    {
        protected readonly DbSet<T> dbSet;
        protected readonly ApiDbContext db;
        public BaseRepository(ApiDbContext db)
        {
            this.db = db ?? throw new ArgumentException(nameof(db));
            dbSet = db.Set<T>();
        }

        public virtual async Task<bool> AddAsync(T entity)
        {
            if (entity == null)
                throw new ArgumentNullException(nameof(entity));
                await dbSet.AddAsync(entity);
            return await db.SaveChangesAsync() > 0;
        }

        public virtual async Task<bool> DeleteAsync(T entity)
        {
            if (entity == null)
                throw new ArgumentNullException(nameof(entity));
            dbSet.Remove(entity);
            return await db.SaveChangesAsync() > 0;
        }

        public virtual async Task<bool> DeleteByIdAsync(int id)
        {
            var entity = await GetByIdAsync(id);
            if (entity == null)
            {
                return false;
            }
            return await DeleteAsync(entity);
        }

        public virtual async Task<IEnumerable<T>> GetAllAsync()
        {
            return await dbSet.ToListAsync();
        }

        public virtual async Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> predicate)
        {
            return await dbSet.Where(predicate).ToListAsync();
        }

        public virtual async Task<T> GetByIdAsync(int id)
        {
            return await dbSet.FindAsync(id);
        }

        public IQueryable<T> Query()
        {
            return dbSet.AsQueryable();
        }

        public async Task<bool> UpdateAsync(T entity)
        {
            if (entity == null)
                throw new ArgumentNullException(nameof(entity));
            dbSet.Update(entity);
            return await db.SaveChangesAsync() > 0;
        }
        public virtual async Task<T> GetByConditionAsync(Expression<Func<T, bool>> predicate)
        {
            return await dbSet.FirstOrDefaultAsync(predicate);
        }
        public void Dispose()
        {
            db.Dispose();
            GC.SuppressFinalize(this);
        }

    }
}
